/**
 * @Author: zhongyang
 * @Date: 2022/6/27 17:11
 */

package main

import "fmt"

/**
13_享元模式
概念：运用共享技术有效地支持大量细粒度的对象。
享元（Flyweight）的核心思想很简单：如果一个对象实例一经创建就不可变，那么反复创建相同的实例就没有必要，
							  直接向调用方返回一个共享的实例就行，这样即节省内存，又可以减少创建对象的过程，提高运行速度。
*/

type ImageFlyweight struct {
	data string
}

func NewImageFlyweight(data string) *ImageFlyweight {
	d := fmt.Sprintf("image data:%s", data)
	return &ImageFlyweight{data: d}
}

func (i *ImageFlyweight) Data() string {
	return i.data
}

type ImageFlyweightFactory struct {
	maps map[string]*ImageFlyweight
}

func (i *ImageFlyweightFactory) Get(fileName string) *ImageFlyweight {
	image := i.maps[fileName]
	if image == nil {
		image = NewImageFlyweight(fileName)
		i.maps[fileName] = image
	}
	return image
}

var imageFactory *ImageFlyweightFactory // 使用全局变量进行共享

func GetImageFlyWeightFactory() *ImageFlyweightFactory {
	// 防止重复创建
	if imageFactory == nil {
		imageFactory = &ImageFlyweightFactory{maps: make(map[string]*ImageFlyweight)}
	}
	return imageFactory
}

//图片浏览器
type ImageViewer struct {
	*ImageFlyweight
}

func (i *ImageViewer) Display() {
	fmt.Printf("显示图片：%v\n", i.data)
}
func NewImageViewer(filename string) *ImageViewer {
	imageFlyweight := GetImageFlyWeightFactory().Get(filename)
	return &ImageViewer{
		ImageFlyweight: imageFlyweight,
	}
}

func main() {
	imageViewer := NewImageViewer("image1.png")
	imageViewer.Display()
	viewer1 := NewImageViewer("img1")
	viewer2 := NewImageViewer("img1")
	if *viewer1 == *viewer2 { //2个指针指向同一个地址，共享模式
		fmt.Println("共享模式")
	} else {
		fmt.Println("非共享模式")
	}
}
